package com.meme.editor.model.sprite2d;

import java.awt.Graphics2D;
import java.awt.Color;
import java.util.ListIterator;

import org.apache.log4j.Logger;

import com.meme.editor.EntityObject;
import com.meme.editor.EntityRefLink;
import com.meme.editor.PropertyValueModification;
import com.meme.editor.PropertyValueModificationList;
import com.meme.editor.property.PropertyFactory;

public class ModulePart extends ModuleRef
{
	
	static Logger logger = Logger.getLogger (ModulePart.class);
	
	final static String GroupName_ModulePartGroup = "Module Part";
	final static String PropertyName_OffsetX        = "Offset X";
	final static String PropertyName_OffsetY        = "Offset Y";
	final static String PropertyName_FlipX        = "Flip X";
	final static String PropertyName_FlipY        = "Flip Y";
	final static String PropertyName_Palette        = "Palette";
	

	
	// x, y in parent coordinates
	int mOffsetX;
	int mOffsetY;
	boolean mFlipX;
	boolean mFlipY;
	int mPaletteID;
	int mFlags;
	
	public ModulePart ()
	{
		this (null);
	}
	
	public ModulePart (Module module)
	{
		this (module, 0, 0, 0, 0);
	}
	
	public ModulePart (Module module, int offX, int offY)
	{
		this (module, offX, offY, 0, 0);
	}	
	
	public ModulePart (Module module, int offX, int offY, int flags, int palID)
	{
		super (module);
		
		createPropertyGroup (GroupName_ModulePartGroup);
		createPublicProperty (GroupName_ModulePartGroup, PropertyName_OffsetX, PropertyFactory.ValueType_Number );
		createPublicProperty (GroupName_ModulePartGroup, PropertyName_OffsetY, PropertyFactory.ValueType_Number );
		createPublicProperty (GroupName_ModulePartGroup, PropertyName_FlipX, PropertyFactory.ValueType_Boolean );
		createPublicProperty (GroupName_ModulePartGroup, PropertyName_FlipY, PropertyFactory.ValueType_Boolean );
		createPublicProperty (GroupName_ModulePartGroup, PropertyName_Palette, PropertyFactory.ValueType_Number );

		
		setOffsetX   (offX);
		setOffsetY   (offY);
		setFlags     (flags);
		setPaletteID (palID);
		
		// build property manager
	}
	
	@Override
	public String getDefaultName ()
	{
		return "Part";
	}
	
	@Override
	protected void _handleModifyingPropertyValues (PropertyValueModificationList modications)
	{		
		ListIterator<PropertyValueModification> iter = modications.listIterator();
		while ( iter.hasNext() )
		{
			PropertyValueModification mod = iter.next();
			
			if (   mod.mGroupName.equals (GroupName_ModulePartGroup) )
			{
				if ( mod.mPropertyName.equals (PropertyName_OffsetX) )
				{
					setOffsetX (( (Float) (mod.mNewValue) ).intValue());
					iter.remove();
				}
				else if ( mod.mPropertyName.equals (PropertyName_OffsetY) )
				{
					setOffsetY (( (Float) (mod.mNewValue) ).intValue());
					iter.remove();
				}
				else if ( mod.mPropertyName.equals (PropertyName_FlipX) )
				{
					setFlipX (( (Boolean) (mod.mNewValue) ).booleanValue());
					iter.remove();
				}
				else if ( mod.mPropertyName.equals (PropertyName_FlipY) )
				{
					setFlipY (( (Boolean) (mod.mNewValue) ).booleanValue());
					iter.remove();
				}
				else if ( mod.mPropertyName.equals (PropertyName_Palette) )
				{
					setPaletteID (( (Float) (mod.mNewValue) ).intValue());
					iter.remove();
				}
			}
		}
			
		super._handleModifyingPropertyValues (modications);
	}	
	
	
	public void setOffsetX (int offX)
	{
		mOffsetX   = offX;
		changePublicPropertyValue ( GroupName_ModulePartGroup, PropertyName_OffsetX, new Float (mOffsetX) );
	}
	
	public void setOffsetY (int offY)
	{
		mOffsetY   = offY;
		changePublicPropertyValue ( GroupName_ModulePartGroup, PropertyName_OffsetY, new Float (mOffsetY) );
	}
	
	public int getOffsetX ()
	{
		return mOffsetX;
	}
	
	public int getOffsetY ()
	{
		return mOffsetY;
	}
	
	public void setFlipX (boolean flip)
	{
		mFlipX = flip;
		changePublicPropertyValue ( GroupName_ModulePartGroup, PropertyName_FlipX, new Boolean (mFlipX) );
	}
	
	public boolean isFlipX ()
	{
		return mFlipX;
	}
	
	public void setFlipY (boolean flip)
	{
		mFlipY = flip;
		changePublicPropertyValue ( GroupName_ModulePartGroup, PropertyName_FlipY, new Boolean (mFlipY) );
	}
	
	public boolean isFlipY ()
	{
		return mFlipY;
	}
	
	public void setFlags (int flags)
	{
		mFlags     = flags;;
	}
	
	public int getFlags ()
	{
		return mFlags;
	}
	
	public void setPaletteID (int palID)
	{
		mPaletteID = palID;
		changePublicPropertyValue ( GroupName_ModulePartGroup, PropertyName_Palette, new Float (mPaletteID) );
	}
	
	public int getPaletteID ()
	{
		return mPaletteID;
	}
	
	@Override
	public boolean isValid ()
	{
		if ( getModule () == null )
			return false;
		
		return getModule ().isValid();
	}
	
	@Override
	public int getMinX ()
	{
		if ( getModule () == null )
			return mOffsetX;
		
		return  mOffsetX + ( mFlipX ? - ( getModule ().getMinX() + getModule ().getWidth() ) : getModule ().getMinX() );
	}
	
//	@Override
//	public int getMaxX ()
//	{
//		if ( mModule == null )
//			return mOffsetX;
//		
//		return  mModule.getMaxX() + mOffsetX;
//	}
	
	@Override
	public int getMinY ()
	{
		if ( getModule () == null )
			return mOffsetY;
		
		return  mOffsetY + ( mFlipY ? - ( getModule ().getMinY() + getModule ().getHeight() ) : getModule ().getMinY() );
	}
	
//	@Override
//	public int getMaxY ()
//	{
//		if ( mModule == null )
//			return mOffsetY;
//		
//		return  mModule.getMaxY() + mOffsetY;
//	}
	
	@Override
	public int getWidth ()
	{
		if ( getModule () == null )
			return 0;
	
		return  getModule ().getWidth();
	}
	
	@Override
	public int getHeight ()
	{
		if ( getModule () == null )
			return 0;
	
		return  getModule ().getHeight();
	}
	

	
	@Override
	public void render (Graphics2D g, int posX, int posY, boolean flipX, boolean flipY, int scale, int flags)
	{
		if ( getModule () == null )
			return;
		
		//g.translate(posX, posY);
		int x = posX;
		int y = posY;
		if (flipX)
			x -= mOffsetX * scale;
		else
			x += mOffsetX * scale;
		
		if (flipY)
			y -= mOffsetY * scale;
		else
			y += mOffsetY * scale;
		
		flipX ^= mFlipX;
		flipY ^= mFlipY;
		
//		boolean drawmask = (flags & RenderFlag_MaskImage) != 0;
//		flags &= ~RenderFlag_MaskImage;
		
		getModule ().render(g, x, y, flipX, flipY, scale, flags);
//		if ( drawmask )
//		{
//			Color oldcolor = g.getColor();
//			Color newcolor = new Color (Color.red.getRGB() | 0x8f000000);
//			g.setColor(newcolor);
//			g.fillRect(x, y, width, height)
//			g.setColor (oldcolor);
//		}
		
		//g.translate(-posX, -posY);
	}

}
